//----------------------------------------------------------
    // 性能测试
        // 1.测试环境
        // 2.测试内容
        // 3.测试结果
//----------------------------------------------------------

#include "../src/ymbxlog.hpp"
#include <chrono>


using namespace ymbxlog;
void bench(const std::string &name, size_t trd_cnt, size_t msg_cnt, size_t msg_len)
{
    Logger::ptr lp = GetLogger(name);
    if(lp.get()==nullptr){
        return;
    }
    std::cout<<"测试开始"<<std::endl;
    std::vector<std::thread> threads;
    std::vector<double> trds_time(trd_cnt);
    std::string tmp(msg_len, 'a');
    size_t msg_cnt_per_trd = msg_cnt / trd_cnt;
    size_t msg_size_per_trd = msg_cnt * msg_len / (trd_cnt*1024);
    for (int i = 0; i < trd_cnt; ++i)
    {
        threads.emplace_back([&, i]()
        {
                auto start = std::chrono::high_resolution_clock::now();
                for (int j = 0; j < msg_cnt_per_trd;++j){
                    lp->fatal("%s", tmp);
                }
                auto end=std::chrono::high_resolution_clock::now();
                auto time_gap=std::chrono::duration_cast<std::chrono::duration<double>>(end-start);
                trds_time[i]=time_gap.count();
                std::cout << "线程[" << i << "]" << "输出日志数：" << msg_cnt_per_trd << "条,总大小："<<msg_size_per_trd<<"kb,总耗时：" << time_gap.count() << "s\n";
                std::cout << "\t每秒输出日志数：" << (size_t)msg_cnt_per_trd / time_gap.count() << "条\n";
                std::cout<<"\t每秒输出日志大小："<<   (size_t)msg_size_per_trd/time_gap.count()<<"kb\n";
        });
    }
    for (auto &trd : threads){
        trd.join();
    }
    double max_cost = 0;
    for (int i = 0;i<trd_cnt;++i){
        if(trds_time[i]>max_cost){
            max_cost = trds_time[i];
        }
    }
    std::cout << "总耗时:" << max_cost << std::endl;
    std::cout << "平均每秒输出日志数：" << msg_cnt / max_cost << "条"<<std::endl;
    std::cout << "平均每秒日志输出大小：" << msg_cnt * msg_len / (max_cost * 1024) << "kb"<<std::endl;
}
void sync_bench(size_t trd_cnt, size_t msg_cnt, size_t msg_len)
{
    std::unique_ptr<LoggerBuilder> uplb(new GlobalLoggerBuild());
    uplb->BuildLoggername("synclogger");
    uplb->BuildLimitLevel(LogLevel::Level::DEBUG);
    uplb->EnableLoggerSync();
    uplb->BuildFormatter();
    uplb->BuildSink<FileSink>("./log/synclogger.txt");
    uplb->Build();
    bench("synclogger", trd_cnt, msg_cnt, msg_len);
}
void async_bench(size_t trd_cnt, size_t msg_cnt, size_t msg_len, size_t consumer_trd_cnt)
{
    std::unique_ptr<LoggerBuilder> uplb(new GlobalLoggerBuild());
    uplb->BuildLoggername("asynclogger");
    uplb->BuildLimitLevel(LogLevel::Level::DEBUG);
    uplb->EnableLoggerAsync();
    uplb->BuildFormatter();
    uplb->BuildAsyncThreadCnt(consumer_trd_cnt);
    uplb->BuildSink<FileSink>("./log/asynclogger.txt");
    uplb->Build();
    bench("asynclogger", trd_cnt, msg_cnt, msg_len);
}
int main()
{
    std::cout<<"性能测试>>>>>"<<std::endl;
    std::cout << "同步单线程百万条日志：\n";
    sync_bench(1, 1000000, 100);
    std::cout << "同步5线程百万条日志：\n";
    sync_bench(5, 1000000, 100);
    std::cout << "同步10线程百万条日志：\n";
    sync_bench(10, 1000000, 100);
    std::cout << "#####################################\n";
    std::cout << "异步单生产单消费线程百万条日志：\n";
    async_bench(1, 1000000, 100,1);
    std::cout << "异步5生产单消费线程百万条日志：\n";
    async_bench(5, 1000000, 100,1);
    std::cout << "异步10生产单消费线程百万条日志：\n";
    async_bench(10, 1000000, 100,1);
    std::cout << "#####################################\n";
    std::cout << "异步单生产2消费线程百万条日志：\n";
    async_bench(1, 1000000, 100,2);
    std::cout << "异步5生产2消费线程百万条日志：\n";
    async_bench(5, 1000000, 100,2);
    std::cout << "异步10生产2消费线程百万条日志：\n";
    async_bench(10, 1000000, 100,2);
    std::cout << "#####################################\n";
    std::cout << "异步单生产5消费线程百万条日志：\n";
    async_bench(1, 1000000, 100,5);
    std::cout << "异步5生产5消费线程百万条日志：\n";
    async_bench(5, 1000000, 100,5);
    std::cout << "异步10生产5消费线程百万条日志：\n";
    async_bench(10, 1000000, 100,5);
    return 0;
}